/******************************************************************************
 * Copyright (C) 2015  671643387@qq.com
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 *****************************************************************************/

#include "http_response.h"
#include "node/sys/console.h"
#include <cstdarg>
#include <event2/buffer.h>
using Console = ::node::sys::Console;

namespace node {
    namespace http {

        HttpResponse::HttpResponse(::node::http::HttpRequest *request)
            : request_(request)
            , output_(NULL)
            , init_ok_(true)
            , end_called_(false)
        {
            Initialize();
        }

        HttpResponse::~HttpResponse(void)
        {
            if (output_ != NULL) {
                evbuffer_free(output_);
            }
        }

        void HttpResponse::Initialize(void)
        {
            output_ = evbuffer_new();
            if (output_ == NULL) {
                init_ok_ = false;
                return;
            }
        }

        bool HttpResponse::Write(const char *data, int size)
        {
            return evbuffer_add(output_, data, size) == 0;
        }

        bool HttpResponse::WritePrintf(const char *format, ...)
        {
            ::std::va_list args;
            va_start(args, format);
            bool ok = evbuffer_add_vprintf(output_, format, args) == 0;
            va_end(args);
            return ok;
        }

        void HttpResponse::End(int code, const char *reason, const char *data /* = NULL */)
        {
            if (end_called_) {
                Console::Warning("HttpResponse::End Already called End or EndError\n");
                return;
            }
            end_called_ = true;
            if (data != NULL) {
                Write(data, strlen(data));
            }
            evhttp_send_reply(request_->request_, code, reason, output_);
        }

        void HttpResponse::EndError(int code, const char *reason)
        {
            if (end_called_) {
                Console::Warning("HttpResponse::End Already called End or EndError\n");
                return;
            }
            end_called_ = true;
            evhttp_send_error(request_->request_, code, reason);
        }
    }
}